﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace StyleMVVM.Utilities
{
	public sealed class WeakDelegate
	{
		private readonly WeakReference target;
		private readonly MethodInfo methodInfo;

		public WeakDelegate(object callDelegate)
		{
			Delegate dDelegate = callDelegate as Delegate;

			if (dDelegate == null)
			{
				throw new ArgumentNullException("callDelegate must be a Delegate: " + callDelegate.GetType().FullName);
			}

			target = new WeakReference(dDelegate.Target);

			methodInfo = dDelegate.GetMethodInfo();
		}

		public WeakDelegate(object target, object methodInfo)
		{
			if (!(methodInfo is MethodInfo))
			{
				throw new ArgumentException("methodInfo must be a valid method");
			}

			this.target = new WeakReference(target);
			this.methodInfo = methodInfo as MethodInfo;
		}

		public object Target
		{
			get { return target.Target; }
		}

		public bool IsAlive
		{
			get { return target.IsAlive; }
		}

		public object MethodInfo
		{
			get { return methodInfo; }
		}

		public object Invoke(params object[] parameters)
		{
			object returnTarget = target.Target;

			if (returnTarget != null)
			{
				return methodInfo.Invoke(returnTarget, parameters);
			}

			return null;
		}
	}
}